package com.mars.captcha.captcha.core.utils;


import com.mars.captcha.captcha.core.constant.Constant;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.Random;

/**
 * @author wangqiang
 * @version 1.0
 * @date 2021/3/6 22:16
 */
@Component
public class ValidateCode {

    /**
     * 宽度
     */
    @Value("${mars.captcha.width}")
    private int width;

    /**
     * 高度
     */
    @Value("${mars.captcha.height}")
    private int height;

    /**
     * 干扰线数量
     */
    @Value("${mars.captcha.lineSize}")
    private int lineSize;

    /**
     * 字符数量
     */
    @Value("${mars.captcha.charNum}")
    private int charNum;

    /**
     * 字符类型
     */
    @Value("${mars.captcha.charType}")
    private String charType;


    /*
     *  获取字体
     */
    private Font getFont() {
        return new Font("Times New Roman", Font.PLAIN, 40);
    }

    /*
     *  获取颜色
     */
    private static Color getRandomColor(int fc, int bc) {

        fc = Math.min(fc, 255);
        bc = Math.min(bc, 255);
        Random random = new Random();
        int r = fc + random.nextInt(bc - fc - 16);
        int g = fc + random.nextInt(bc - fc - 14);
        int b = fc + random.nextInt(bc - fc - 12);

        return new Color(r, g, b);
    }

    /*
     *  绘制干扰线
     */
    private void drawLine(Graphics g) {
        Random random = new Random();
        int x = random.nextInt(width);
        int y = random.nextInt(height);
        int xl = random.nextInt(20);
        int yl = random.nextInt(10);
        g.drawLine(x, y, x + xl, y + yl);
    }

    /*
     *  获取随机字符
     */
    private String getRandomString(int num) {
        Random random = new Random();
        if (charType.equals(Constant.CAPTCHA_TYPE_CHAR)) {
            num = num > 0 ? num : Constant.RAND_STRING.length();
            return String.valueOf(Constant.RAND_STRING.charAt(random.nextInt(num)));
        } else {
            num = num > 0 ? num : Constant.RAND_NUM.length();
            return String.valueOf(Constant.RAND_NUM.charAt(random.nextInt(num)));
        }

    }

    /*
     *  绘制字符串
     */
    private String drawString(Graphics g, String randomStr, int i) {
        Random random = new Random();
        g.setFont(getFont());
        g.setColor(getRandomColor(108, 190));
        String rand = "";
        if (charType.equals(Constant.CAPTCHA_TYPE_CHAR)) {
            rand = getRandomString(random.nextInt(Constant.RAND_STRING.length()));
        } else {
            rand = getRandomString(random.nextInt(Constant.RAND_NUM.length()));
        }
        randomStr += rand;
        g.translate(random.nextInt(3), random.nextInt(6));
        g.drawString(rand, 40 * i + 10, 25);
        return randomStr;
    }

    /*
     *  生成随机图片
     */
    public String getRandomCodeImage(HttpServletRequest request, HttpServletResponse response) {
        HttpSession session = request.getSession();
        // BufferedImage类是具有缓冲区的Image类,Image类是用于描述图像信息的类
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_BGR);
        Graphics g = image.getGraphics();
        g.fillRect(0, 0, width, height);
        g.setColor(getRandomColor(105, 189));
        g.setFont(getFont());
        // 绘制干扰线
        for (int i = 0; i < (lineSize); i++) {
            drawLine(g);
        }
        // 绘制随机字符
        String random_string = "";
        for (int i = 0; i < (charNum); i++) {
            random_string = drawString(g, random_string, i);
        }
        g.dispose();
        try {
            //  直接返回图片
            ImageIO.write(image, "PNG", response.getOutputStream());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return random_string;
    }
}
